#include <iostream>
#include <pthread.h>
#include <vector>
#include "Thread.hpp"

using namespace ThreadModule;

#define NUM 4

int ticketnum = 10000;
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

struct ThreadData
{
    std::string name;
    pthread_mutex_t* pmtx;
};

void GetTicket(ThreadData* td)
{
    while (1)
    {
        pthread_mutex_lock(td->pmtx);
        if (ticketnum > 0)
        {
            usleep(1000);
            printf("%s[%ld]get a ticket: %d\n", td->name.c_str(), pthread_self(), ticketnum--);
            pthread_mutex_unlock(td->pmtx);
            usleep(50);
        }
        else
        {
            pthread_mutex_unlock(td->pmtx);
            break;
        }
    }
}

int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);
    std::vector<Thread<ThreadData>> v;
    for (int i = 0; i < NUM; i++)
    {
        ThreadData* td = new ThreadData;
        v.push_back(Thread<ThreadData>(GetTicket, td));
        td->name = v[i].Name();
        td->pmtx = &mutex;
    }

    for (int i = 0; i < NUM; i++)
    {
        v[i].Start();
    }

    for (int i = 0; i < NUM; i++)
    {
        v[i].Join();
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}